using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

namespace SyncSocketModuleCore.SyncSocketModule
{
	public class SyncSocketServices
	{
		public event EventHandler<(bool,string)> SocketStatusChanged;
		private CancellationToken _token;
		private CancellationTokenSource _cancellationTokenSource;
		private SyncSocketClient m_SocketClient;

		private CommStep m_CurrentCommStep;

		private CommStep m_BeforeCommStep;

		private int m_CurrentTryConnectPort;

		
		

		private IPacketHandler m_PacketHandler;

		private bool m_RequestOperationStop;

		private object ReadWriteWordLock = new object();

		private byte[] RecvByteBuffer = new byte[2048];

		private Stopwatch m_RunningLogStopWatch = new Stopwatch();

		private EnumPlcAccessMode m_CurrentPlcAccessMode;

		private DateTime m_ConnectionRequestTime = DateTime.Now;

		private int m_TryConnectionPeriodBySec = 10;

		private int m_WaitTerminateTime = 10000;

		private int m_ThreadCommStepPollingTime = 1000;

		private int m_CurrentReadTryCount;

		private int m_CurrentWriteTryCount;

		private string m_ServiceName = "None";

		private string m_IPAddress = "127.0.0.1";

		private int m_Id;

		private int m_Port;

		private int m_PortRange;

		private int m_ConnectionCheckCount;

		
		
		public SyncSocketServices(string _Name, int _ID, string _IPAddress, int _Port, int _PortRange, int _TryConnectionPeriodBySec, int _SendTimeoutBySec, int _RecvTimeoutBySec)
		{
			this.m_ServiceName = _Name;
			this.m_Id = _ID;
			this.m_IPAddress = _IPAddress;
			this.m_Port = _Port;
			this.m_PortRange = _PortRange;
			this.m_TryConnectionPeriodBySec = _TryConnectionPeriodBySec;
			this.m_CurrentTryConnectPort = this.m_Port;
			this.m_SocketClient = new SyncSocketClient(this.m_Id, this.m_ServiceName);
			
			this.m_SocketClient.SetSendTimeout(_SendTimeoutBySec);
			this.m_SocketClient.SetReceiveTimeout(_RecvTimeoutBySec);


			this.m_SocketClient.OnErrorLogHandler += M_SocketClient_OnErrorLogHandler;
        }
		/// <summary>
		/// socket连接失败
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void M_SocketClient_OnErrorLogHandler(object? sender, SyncSocketClientErrorArgs e)
		{
            object[] objArray = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, e.Message };
            this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  OnError Occure  Msg : {3}", objArray), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);

			SocketStatusChanged?.Invoke(this, (false,e.Message));
        }

		public void CommStepChangeTo(CommStep _ChangeTo)
		{
			this.m_BeforeCommStep = this.m_CurrentCommStep;
			this.m_CurrentCommStep = _ChangeTo;
		}

		private void ConnectionChangedEventProc(bool _CurrentConnection)
		{
			if (this.OnConnectionChangedHandler == null)
			{
				return;
			}
			ConnectChangeEventArgs connectChangeEventArg = new ConnectChangeEventArgs()
			{
				BeforeConnection = !_CurrentConnection,
				CurrentConnection = _CurrentConnection
			};
			this.OnConnectionChangedHandler(this, connectChangeEventArg);
		}

		private void CurrentStepLogging()
		{
			if (this.m_CurrentCommStep == CommStep.Run)
			{
				if (this.m_RunningLogStopWatch.Elapsed.TotalSeconds < 5)
				{
					return;
				}
				this.m_RunningLogStopWatch.Stop();
				this.m_RunningLogStopWatch.Reset();
				this.m_RunningLogStopWatch.Start();
			}
			string str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2}", this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode);
			this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
		}

		private void DoingWcfRecvSchedule()
		{
			this.CurrentStepLogging();
			switch (this.m_CurrentCommStep)
			{
				case CommStep.WaitInit:
				{
					if (!this.m_RequestOperationStop)
					{
						break;
					}
					this.CommStepChangeTo(CommStep.WaitDisConnect);
					return;
				}
				case CommStep.Init:
				{
					if (this.m_RequestOperationStop)
					{
						this.CommStepChangeTo(CommStep.WaitDisConnect);
					}
					this.Proc_CommStepInit();
					return;
				}
				case CommStep.WaitConnect:
				{
					if (!this.m_RequestOperationStop)
					{
						this.Proc_CommStepWaitConnect();
						return;
					}
					this.CommStepChangeTo(CommStep.WaitDisConnect);
					return;
				}
				case CommStep.Run:
				{
					if (!this.m_RequestOperationStop)
					{
						this.ProcCommStepRun();
						return;
					}
					this.CommStepChangeTo(CommStep.WaitDisConnect);
					return;
				}
				case CommStep.WaitDisConnect:
				{
					this.Proc_CommStepWaitDisconnect();
					break;
				}
				default:
				{
					return;
				}
			}
		}

		private void InitEvents()
		{
			this.CommStepChangeTo(CommStep.Init);
			
		}

		public bool IsConnected()
		{
			return this.m_SocketClient.IsConnected();
		}

		private void LogProc(string _LogMsg, SyncSocketServiceLogEventArgs.LogMsgCase _LogCase = 0)
		{
			if (this.OnSyncSocketServiceLogHandler == null)
			{
				return;
			}
			SyncSocketServiceLogEventArgs syncSocketServiceLogEventArg = new SyncSocketServiceLogEventArgs()
			{
				Message = _LogMsg
			};
			this.OnSyncSocketServiceLogHandler(this, syncSocketServiceLogEventArg);
		}

		

		public bool OperationInit()
		{
			return true;
		}

		public bool OperationPasue()
		{
			this.m_RunningLogStopWatch.Stop();
			return true;
		}

		public bool OperationResume()
		{
			this.m_RunningLogStopWatch.Start();
			return true;
		}

		public bool OperationStart(CancellationTokenSource tokenSource,CancellationToken token,int pollingTime=1000)
		{
			_cancellationTokenSource = tokenSource;
			_token = token;
			this.m_RequestOperationStop = false;
			this.m_ThreadCommStepPollingTime = pollingTime;
			this.RunThreadCommStep();
			this.m_RunningLogStopWatch.Start();
			return true;
		}

		public bool OperationStop()
		{
			this.m_RequestOperationStop = true;

			this.Proc_CommStepWaitDisconnect();
			
			this.InitEvents();
			
			
			return true;
		}

		private void Proc_CommStepInit()
		{
			this.InitEvents();
			this.m_CurrentReadTryCount = 0;
			this.m_CurrentWriteTryCount = 0;
			this.m_CurrentPlcAccessMode = EnumPlcAccessMode.None;
			this.CommStepChangeTo(CommStep.WaitConnect);
		}

        private void Proc_CommStepWaitConnect()
        {
            string LogMsg = "";
            bool ConnectRet = false;
            if (m_SocketClient.IsConnected())
            {
                m_SocketClient.Close();
                LogMsg = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", m_CurrentCommStep.ToString().PadRight(15), m_BeforeCommStep.ToString().PadRight(15), m_CurrentPlcAccessMode, "Occurs when connected to socket during connection (attempt to connect after disconnection) : Port Number : " + m_CurrentTryConnectPort);
                LogProc(LogMsg);
                ConnectionChangedEventProc(_CurrentConnection: false);
            }
            TimeSpan ConnectionTerm = DateTime.Now - m_ConnectionRequestTime;
            if (ConnectionTerm.TotalSeconds < (double)m_TryConnectionPeriodBySec)
            {
                int WaitTime = m_TryConnectionPeriodBySec - (int)ConnectionTerm.TotalSeconds;
                if (WaitTime > 0)
                {
                    return;
                }
            }
            ConnectRet = m_SocketClient.Connect(m_IPAddress, m_CurrentTryConnectPort);
            m_ConnectionRequestTime = DateTime.Now;
            if (ConnectRet)
            {
                LogMsg = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", m_CurrentCommStep.ToString().PadRight(15), m_BeforeCommStep.ToString().PadRight(15), m_CurrentPlcAccessMode, "begin connect : Port Number : " + m_CurrentTryConnectPort);
                LogProc(LogMsg);
                if (m_PacketHandler.IsNeedNodeSync())
                {
                    ReadNodeAddress();
                }
                if (m_PacketHandler.IsReqeustSync() && !ReqeustSync())
                {
                    m_SocketClient.Close();
                    LogMsg = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", m_CurrentCommStep.ToString().PadRight(15), m_BeforeCommStep.ToString().PadRight(15), m_CurrentPlcAccessMode, "Request/Setup Connection Fail : Port Number : " + m_CurrentTryConnectPort);
                    LogProc(LogMsg);
                    ConnectionChangedEventProc(_CurrentConnection: false);
                }
                else
                {
                    ConnectionChangedEventProc(_CurrentConnection: true);
                    CommStepChangeTo(CommStep.Run);
                }
            }
            else
            {
                LogMsg = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", m_CurrentCommStep.ToString().PadRight(15), m_BeforeCommStep.ToString().PadRight(15), m_CurrentPlcAccessMode, "connection failure Port Number  : " + m_CurrentTryConnectPort + " -> " + ((m_CurrentTryConnectPort + 1 > m_PortRange) ? m_Port : (m_CurrentTryConnectPort + 1)));
                LogProc(LogMsg);
                m_CurrentTryConnectPort++;
                if (m_CurrentTryConnectPort > m_PortRange)
                {
                    m_CurrentTryConnectPort = m_Port;
                }
            }
        }

        private void Proc_CommStepWaitDisconnect()
		{
			string str = "";
			this.m_ConnectionRequestTime = DateTime.Now;
			if (!this.m_SocketClient.IsConnected())
			{
				str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,   Socket 连接失败 ", this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode);
				this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
				if (this.m_RequestOperationStop)
				{
					
					return;
				}
				this.CommStepChangeTo(CommStep.Init);
				return;
			}
			if (!this.m_SocketClient.Close())
			{
				str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,   断开连接失败", this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode);
				this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
				if (this.m_RequestOperationStop)
				{
					
					return;
				}
				this.CommStepChangeTo(CommStep.Init);
				return;
			}
			str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,   重连成功", this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode);
			this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
			this.ConnectionChangedEventProc(false);
			if (this.m_RequestOperationStop)
			{
				
				return;
			}
			this.CommStepChangeTo(CommStep.Init);
		}

		private void ProcCommStepRun()
		{
			string str = "";
			if (this.m_SocketClient.IsConnected())
			{
				this.m_ConnectionCheckCount = 0;
			}
			else
			{
				this.m_ConnectionCheckCount++;
				if (this.m_ConnectionCheckCount > 3)
				{
					str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,   意外断开 (Step To WaitDisConnect)", this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode);
					this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					this.ConnectionChangedEventProc(false);
					this.CommStepChangeTo(CommStep.WaitDisConnect);
					this.m_ConnectionCheckCount = 0;
					Console.WriteLine(string.Format("检查连接. IP: {0}_PORT :{1}", this.m_IPAddress, this.m_Port));
					return;
				}
			}
		}

		private bool ReadNodeAddress()
		{
			bool flag;
			try
			{
				string str = "";
				byte[] numArray = null;
				string empty = string.Empty;
				SocketError socketError = SocketError.SocketError;
				SocketError socketError1 = SocketError.SocketError;
				Array.Clear(this.RecvByteBuffer, 0, (int)this.RecvByteBuffer.Length);
				if (!this.m_PacketHandler.ReadNodeAddress(out numArray, out str))
				{
					flag = false;
				}
				else if (this.m_SocketClient != null)
				{
					if (this.m_SocketClient.ReceiveBufferClear("") > 0)
					{
						object[] objArray = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, "ReadCmdPacket Receive Buffer deleted" };
						str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray);
						this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					}
					if (this.m_SocketClient.Send(ref numArray, (int)numArray.Length, out socketError, "Request Node Number") == (int)numArray.Length)
					{
						int num = 24;
						int num1 = this.m_SocketClient.Receive(this.RecvByteBuffer, num, out socketError1, "Request Node Number");
						if (this.m_PacketHandler.ReadNodeResponse(this.RecvByteBuffer, num1, num, 0, out str))
						{
							flag = true;
						}
						else
						{
							object[] objArray1 = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, string.Concat("ReadCmdPacket Receive fail ", empty) };
							str = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray1);
							this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
							flag = false;
						}
					}
					else
					{
						flag = false;
					}
				}
				else
				{
					flag = false;
				}
			}
			catch (Exception exception1)
			{
				Exception exception = exception1;
				this.LogProc(exception.Message, SyncSocketServiceLogEventArgs.LogMsgCase.Exception);
				
				flag = false;
			}
			return flag;
		}

		public bool ReadWord(byte[] pRxBuff, int nStaddr, int ReadCnt, int DeviceCode, int DBBlock = 0)
		{
			if (this.m_CurrentCommStep != CommStep.Run || !this.m_SocketClient.IsConnected())
			{
				return false;
			}
			bool flag = false;
			lock (this.ReadWriteWordLock)
			{
				try
				{
					this.m_CurrentPlcAccessMode = EnumPlcAccessMode.PLC_READ;
					flag = this.ReadWordLock(pRxBuff, nStaddr, ReadCnt, DeviceCode, DBBlock);
					if (!flag)
					{
						object[] objArray = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, null };
						
						int mCurrentReadTryCount = m_CurrentReadTryCount;
						int num = mCurrentReadTryCount;
						m_CurrentReadTryCount = mCurrentReadTryCount + 1;
						objArray[3] = string.Concat("ReadWord() fail ReadTryCount : ", num);
						this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					}
					else
					{
						this.m_CurrentReadTryCount = 0;
					}
					this.m_CurrentPlcAccessMode = EnumPlcAccessMode.None;
				}
				catch (Exception exception1)
				{
					Exception exception = exception1;
					this.LogProc(exception.Message, SyncSocketServiceLogEventArgs.LogMsgCase.Exception);
					
					object[] objArray1 = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, null };
					SyncSocketServices syncSocketService1 = this;
					int mCurrentReadTryCount1 = syncSocketService1.m_CurrentReadTryCount;
					int num1 = mCurrentReadTryCount1;
					syncSocketService1.m_CurrentReadTryCount = mCurrentReadTryCount1 + 1;
					objArray1[3] = string.Concat("ReadWord()  ReadTryCount : ", num1);
					this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray1), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					this.m_CurrentPlcAccessMode = EnumPlcAccessMode.None;
				}
			}
			return flag;
		}
		/// <summary>
		/// 读取数据
		/// </summary>
		/// <param name="pRxBuff"></param>
		/// <param name="nStaddr"></param>
		/// <param name="ReadCnt"></param>
		/// <param name="DeviceCode"></param>
		/// <param name="DBBlock"></param>
		/// <returns></returns>
		private bool ReadWordLock(byte[] pRxBuff, int nStaddr, int ReadCnt, int DeviceCode, int DBBlock = 0)
		{
			int num;
			string str;
			byte[] numArray = null;
			SocketError socketError = SocketError.SocketError;
			SocketError socketError1 = SocketError.SocketError;
			Array.Clear(this.RecvByteBuffer, 0, (int)this.RecvByteBuffer.Length);

			// 开辟 numArray
			if (!this.m_PacketHandler.BatchReadPacket(nStaddr, ReadCnt, (int)DeviceCode, out num, out numArray, out str, DBBlock))
			{
				return false;
			}
			if (this.m_SocketClient == null)
			{
				return false;
			}
			// 清空
			int num1 = this.m_SocketClient.ReceiveBufferClear("");

			if (num1 > 0)
			{
				object[] objArray = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, string.Concat("ReadCmdPacket Receive Buffer delete complete : ", num1.ToString()) };
				this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
			}
			
			int length = (int)numArray.Length;

			string[] strArrays = new string[] { "Device Code : ", DeviceCode.ToString(), " ReadStartAddr : ", nStaddr.ToString(), " ReadCnt : ", ReadCnt.ToString() };
			if (m_SocketClient.Send(ref numArray, length, out socketError, string.Concat(strArrays)) != (int)numArray.Length)
			{
				return false;
			}
			int num2 = 0;
			if (this.m_PacketHandler.IsReqeustSync())
			{
				
				
				string[] str1 = new string[] { "Device Code : ", DeviceCode.ToString(), " ReadStartAddr : ", nStaddr.ToString(), " ReadCnt : ", ReadCnt.ToString() };
				// 获取数据
				num2 = m_SocketClient.Receive(this.RecvByteBuffer, 4, out socketError1, string.Concat(str1));
			}
			 
			
			string[] strArrays1 = new string[] { "Device Code : ", DeviceCode.ToString(), " ReadStartAddr : ", nStaddr.ToString(), " ReadCnt : ", ReadCnt.ToString() };
			num2 = this.m_SocketClient.Receive(this.RecvByteBuffer, num, out socketError1, string.Concat(strArrays1));
			if (this.m_PacketHandler.BatchReadResponse(this.RecvByteBuffer, num2, num, ReadCnt, ref pRxBuff, out str))
			{
				return true;
			}
			
			object[] objArray1 = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, string.Concat("ReadCmdPacket Receive ", str) };
			this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray1), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
			return false;
		}

		private bool ReqeustSync()
		{
			bool flag;
			try
			{
				int num = 0;
				int num1 = 1;
				byte[] numArray = new byte[] { 3, 0, 0, 22, 17, 224, 0, 0, 0, 46, 0, 193, 2, 1, 0, 194, 2, 3, 0, 192, 1, 10 };
				numArray[18] = (byte)(num << 5 | num1);
				byte[] numArray1 = numArray;
				string str = "";
				if (this.m_SocketClient != null)
				{
					int num2 = this.m_SocketClient.ReceiveBufferClear("");
					SocketError socketError = SocketError.SocketError;
					SocketError socketError1 = SocketError.SocketError;
					if (num2 > 0)
					{
						object[] objArray = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, "ReadCmdPacket Receive Buffer 삭제 완료" };
						this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					}
					if (this.m_SocketClient.Send(ref numArray1, (int)numArray1.Length, out socketError, "Request Connnection") != (int)numArray1.Length)
					{
						flag = false;
					}
					else if (this.m_SocketClient.Receive(this.RecvByteBuffer, 4, out socketError1, "Request Connnection") < 4)
					{
						str = string.Format("Reqeust Connect Data not Exist", new object[0]);
						flag = false;
					}
					else if (this.m_SocketClient.Receive(this.RecvByteBuffer, 18, out socketError1, "Request Connnection") < 18)
					{
						str = string.Format("Reqeust Connect Data not Exist", new object[0]);
						flag = false;
					}
					else if (this.RecvByteBuffer[1] == 208 )
					{
						byte[] numArray2 = new byte[] { 3, 0, 0, 25, 2, 240, 128, 50, 1, 0, 0, 255, 255, 0, 8, 0, 0, 240, 0, 0, 3, 0, 3, 3, 192 };
						if (this.m_SocketClient.Send(ref numArray2, (int)numArray2.Length, out socketError, "SetupConnection Connnection") != (int)numArray2.Length)
						{
							flag = false;
						}
						else if (this.m_SocketClient.Receive(this.RecvByteBuffer, 4, out socketError1, "SetupConnection Connnection") < 4)
						{
							str = string.Format("Not enough data received in response to Communication Setup", new object[0]);
							flag = false;
						}
						else if (this.m_SocketClient.Receive(this.RecvByteBuffer, 23, out socketError1, "SetupConnection Connnection") < 23)
						{
							str = string.Format("Not enough data received in response to Communication Setup", new object[0]);
							flag = false;
						}
						else if (this.RecvByteBuffer[4] == 3)
						{
							return true;
						}
						else
						{
							str = string.Format("Error reading Communication Setup response", new object[0]);
							this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
							flag = false;
						}
					}
					else
					{
						str = string.Format("Connection request was denied", new object[0]);
						this.LogProc(str, SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
						flag = false;
					}
				}
				else
				{
					flag = false;
				}
			}
			catch (Exception exception1)
			{
				Exception exception = exception1;
				this.LogProc(exception.Message, SyncSocketServiceLogEventArgs.LogMsgCase.Exception);
				
				flag = false;
			}
			return flag;
		}

		private void RunThreadCommStep()
		{		
			this.InitEvents();
			var task = Task.Factory.StartNew(async () =>
			{
				await this.ThreadCommStepScheduler();

            }, _token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
		
		}

		public void SetPacketHandler(IPacketHandler _PacketHandler)
		{
			this.m_PacketHandler = _PacketHandler;
		}

		public void SetTimeInfo(int _TryConnectionPeriodBySec, int _SendTimeoutBySec, int _RecvTimeoutBySec)
		{
			this.m_TryConnectionPeriodBySec = _TryConnectionPeriodBySec;
			this.m_SocketClient.SetSendTimeout(_SendTimeoutBySec);
			this.m_SocketClient.SetReceiveTimeout(_RecvTimeoutBySec);
		}

		

		private async Task ThreadCommStepScheduler()
		{
			while (true)
			{
				try
				{	
					if(_token.IsCancellationRequested || _cancellationTokenSource.IsCancellationRequested)
					{
						break;
					}
						this.DoingWcfRecvSchedule();

						await Task.Delay(m_ThreadCommStepPollingTime);					
				}
				catch (Exception exception1)
				{
					Exception exception = exception1;
					
				}
			}
			
		}

		public bool WriteWord(int[] pTxBuff, int nStaddr, int writeWordCount, int DeviceCode, int DBBlock = 0)
		{
			if (this.m_CurrentCommStep != CommStep.Run || !this.m_SocketClient.IsConnected())
			{
				return false;
			}
			bool flag = false;
			lock (this.ReadWriteWordLock)
			{
				try
				{
					this.m_CurrentPlcAccessMode = EnumPlcAccessMode.PLC_WRITE;
					flag = this.WriteWordLock(pTxBuff, nStaddr, writeWordCount, DeviceCode, DBBlock);
					if (!flag)
					{
						object[] objArray = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, null };
						SyncSocketServices syncSocketService = this;
						int mCurrentWriteTryCount = syncSocketService.m_CurrentWriteTryCount;
						int num = mCurrentWriteTryCount;
						syncSocketService.m_CurrentWriteTryCount = mCurrentWriteTryCount + 1;
						objArray[3] = string.Concat("WriteWord() fail WriteTryCount : ", num);
						this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3},  ", objArray), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					}
					else
					{
						this.m_CurrentWriteTryCount = 0;
					}
					this.m_CurrentPlcAccessMode = EnumPlcAccessMode.None;
				}
				catch (Exception exception1)
				{
					Exception exception = exception1;
					this.LogProc(exception.Message, SyncSocketServiceLogEventArgs.LogMsgCase.Exception);
					
					object[] objArray1 = new object[] { this.m_CurrentCommStep.ToString().PadRight(15), this.m_BeforeCommStep.ToString().PadRight(15), this.m_CurrentPlcAccessMode, null };
					SyncSocketServices syncSocketService1 = this;
					int mCurrentWriteTryCount1 = syncSocketService1.m_CurrentWriteTryCount;
					int num1 = mCurrentWriteTryCount1;
					syncSocketService1.m_CurrentWriteTryCount = mCurrentWriteTryCount1 + 1;
					objArray1[3] = string.Concat("WriteWord() fail WriteTryCount : ", num1);
					this.LogProc(string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", objArray1), SyncSocketServiceLogEventArgs.LogMsgCase.Normal);
					this.m_CurrentPlcAccessMode = EnumPlcAccessMode.None;
				}
			}
			return flag;
		}

		private bool WriteWordLock(int[] pTxBuff, int nStartaddr, int WriteCnt, int DeviceCode, int DBBlock = 0)
		{
            string LogMsg = "";
            byte[] WriteWordCmdPacket = null;
            SocketError SendError = SocketError.SocketError;
            SocketError RecvError = SocketError.SocketError;
            Array.Clear(RecvByteBuffer, 0, RecvByteBuffer.Length);
            if (!m_PacketHandler.BatchWritePacket(pTxBuff, nStartaddr, WriteCnt, DeviceCode, out var WriteWordCmdAckPacketSize, out WriteWordCmdPacket, out var ErrorText, DBBlock))
            {
                return false;
            }
            if (m_SocketClient == null)
            {
                return false;
            }
            int ReceiveBufferClearCount = m_SocketClient.ReceiveBufferClear();
            if (ReceiveBufferClearCount > 0)
            {
                LogMsg = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", m_CurrentCommStep.ToString().PadRight(15), m_BeforeCommStep.ToString().PadRight(15), m_CurrentPlcAccessMode, "WriteCmdPacket Receive Buffer Delete Complete");
                LogProc(LogMsg);
            }
            int WriteWordCmdPacketSendResultByte = m_SocketClient.Send(ref WriteWordCmdPacket, WriteWordCmdPacket.Length, out SendError, "Device Code : " + DeviceCode + " WriteStartAddr : " + nStartaddr + " WriteCnt : " + WriteCnt);
            if (WriteWordCmdPacketSendResultByte != WriteWordCmdPacket.Length)
            {
                return false;
            }
            int RealRecvCount = m_SocketClient.Receive(RecvByteBuffer, WriteWordCmdAckPacketSize, out RecvError, "Device Code : " + DeviceCode + " WriteStartAddr : " + nStartaddr + " WriteCnt : " + WriteCnt);
            if (!m_PacketHandler.BatchWriteResponse(RecvByteBuffer, RealRecvCount, WriteWordCmdAckPacketSize, WriteCnt, out ErrorText))
            {
                LogMsg = string.Format("CurrentStep : {0} , BeforeStep : {1}, AccessMode : {2} ,  Msg : {3}", m_CurrentCommStep.ToString().PadRight(15), m_BeforeCommStep.ToString().PadRight(15), m_CurrentPlcAccessMode, "WriteCmdPacket Receive Check Fail" + ErrorText);
                LogProc(LogMsg);
                return false;
            }
            return true;
        }

		public event EventHandler<ConnectChangeEventArgs> OnConnectionChangedHandler;

		public event EventHandler<SyncSocketServiceLogEventArgs> OnSyncSocketServiceLogHandler;
	}
}